package com.yeskery.nut.cloud.registry.nacos;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.yeskery.nut.cloud.registry.core.*;
import com.yeskery.nut.util.StringUtils;

import java.util.Collection;
import java.util.stream.Collectors;

/**
 * Nacos服务实例注册器
 * @author YESKERY
 * 2024/1/16
 */
public class NacosServerInstanceRegistry implements ServerInstanceRegistry {

    /** Nacos服务对象 */
    private final NamingService namingService;

    /** 服务 */
    private NacosServer server;

    /**
     * 构建Nacos服务实例注册器
     * @param namingService Nacos服务对象
     */
    public NacosServerInstanceRegistry(NamingService namingService) {
        this.namingService = namingService;
    }

    @Override
    public Server getServer() {
        return server;
    }

    @Override
    public Collection<Instance> getInstances() {
        try {
            return namingService.selectInstances(getServer().name(), true).stream().map(i -> {
                DefaultServerInstanceMetadata serverInstanceMetadata = new DefaultServerInstanceMetadata();
                serverInstanceMetadata.setIp(i.getIp());
                serverInstanceMetadata.setPort(i.getPort());
                serverInstanceMetadata.setScheme("http://");
                serverInstanceMetadata.setStatus(ServerInstanceStatus.OK);
                DefaultInstance instance = new DefaultInstance();
                instance.setId(i.getInstanceId());
                if (StringUtils.isEmpty(instance.id())) {
                    instance.setId(String.valueOf((i.getIp() + i.getPort()).hashCode()));
                }
                instance.setServerInstanceMetadata(serverInstanceMetadata);
                return instance;
            }).collect(Collectors.toList());
        } catch (NacosException e) {
            throw new RegistryException("Nacos Server Instance Obtain Fail.", e);
        }
    }

    @Override
    public void registerInstance(ServerInstanceMetadata metadata) {
        try {
            namingService.registerInstance(getServer().name(), metadata.getIp(), metadata.getPort());
        } catch (NacosException e) {
            throw new RegistryException("Nacos Server Instance Register Fail.", e);
        }
    }

    @Override
    public boolean contains(ServerInstanceMetadata metadata) {
        try {
            return namingService.selectInstances(getServer().name(), true)
                    .stream()
                    .anyMatch(i -> i.getIp().equals(metadata.getIp()) && i.getPort() == metadata.getPort());
        } catch (NacosException e) {
            throw new RegistryException("Nacos Server Instance Obtain Fail.", e);
        }
    }

    @Override
    public void removeInstance(String id) {
        throw new RegistryException("UnSupport Proactively Remove.");
    }

    /**
     * 设置服务对象
     * @param server 服务对象
     */
    public void setServer(NacosServer server) {
        this.server = server;
    }
}
